package cfca.seal.util;

import cfca.sadk.algorithm.common.GMObjectIdentifiers;
import cfca.sadk.asn1.parser.ASN1Parser;
import cfca.sadk.lib.crypto.JCrypto;
import cfca.sadk.lib.crypto.Session;
import cfca.sadk.org.bouncycastle.asn1.ASN1Encodable;
import cfca.sadk.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import cfca.sadk.org.bouncycastle.asn1.ASN1Sequence;
import cfca.sadk.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import cfca.sadk.org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey;
import cfca.sadk.org.bouncycastle.util.encoders.Base64;
import cfca.sadk.util.Signature;
import cfca.sadk.x509.certificate.X509Cert;
import cfca.seal.exception.CodeException;
import java.io.PrintStream;
import java.security.Key;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;

public class SealCertUtil
{
  public static void checkCertMatchKey(String signAlg, String device, X509Cert x509Cert, PrivateKey privateKey, PublicKey pukey)
    throws CodeException
  {
    byte[] testData = "CFCA".getBytes();
    boolean verifySign = false;
    Signature signature = new Signature();
    try {
      JCrypto.getInstance().initialize(device, null);
      Session session = JCrypto.getInstance().openSession(device);
      byte[] sign = signature.p1SignMessage(signAlg, testData, privateKey, session);
      System.out.println(Base64.toBase64String(sign));
      verifySign = signature.p1VerifyMessage(signAlg, testData, sign, x509Cert.getPublicKey(), session);
    } catch (Exception ex1) {
      throw new CodeException("C6006", "验证私钥和公钥证书匹配发生错误", ex1);
    }
    if (!verifySign)
      throw new CodeException("C6007", "私钥和公钥证书不匹配");
  }

  public static Key getRSAPrivateKey(byte[] keyData)
    throws CodeException
  {
    try
    {
      PKCS8EncodedKeySpec p8KeySpec = new PKCS8EncodedKeySpec(keyData);
      PrivateKeyInfo info = PrivateKeyInfo.getInstance(p8KeySpec.getEncoded());
      return new BCRSAPrivateCrtKey(info);
    } catch (Exception e) {
      throw new CodeException("C6008", "私钥和公钥证书不匹配", e);
    }
  }

  public static boolean isSM2(byte[] p12Data)
    throws CodeException
  {
    boolean result = false;

    if (ASN1Parser.isBase64Compatability(p12Data)) {
      p12Data = Base64.decode(p12Data);
    }
    ASN1Sequence seq = ASN1Sequence.getInstance(p12Data);
    if (seq.size() != 3) {
      throw new CodeException("invalid p12Data");
    }

    ASN1Sequence content = ASN1Sequence.getInstance(seq.getObjectAt(1));

    ASN1Encodable oid = content.getObjectAt(0);

    if (GMObjectIdentifiers.sm2Data.equals(oid)) {
      result = true;
    }

    return result;
  }
}